home *** CD-ROM | disk | FTP | other *** search
/ Sound Fx / Sound Fx.iso / Software / UNZIPED / MPW181-5 / _SETUP.1 / synfilt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-21  |  34.5 KB  |  1,107 lines

  1. /* synfilt.cpp
  2.  
  3.     Synthesis Filter implementation */
  4.  
  5. /* -- 03/20/97 --
  6.  *  compute_new_v() -- reoptimized with the assumption that constant offsets
  7.  *    to memory are free.  Common subexpression were redone for better
  8.  *    optimization.
  9.  *  compute_pcm_samples() -- reoptimized with constant offsets.
  10.  *
  11.  *  -- Conrad Wei-Li Song (conradsong@mail.utexas.edu)
  12.  */
  13.  
  14. /*
  15.  *  @(#) synthesis_filter.cc 1.14, last edit: 6/21/94 11:22:20
  16.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  17.  *  @(#) Berlin University of Technology
  18.  *
  19.  *  This program is free software; you can redistribute it and/or modify
  20.  *  it under the terms of the GNU General Public License as published by
  21.  *  the Free Software Foundation; either version 2 of the License, or
  22.  *  (at your option) any later version.
  23.  *
  24.  *  This program is distributed in the hope that it will be useful,
  25.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.  *  GNU General Public License for more details.
  28.  *
  29.  *  You should have received a copy of the GNU General Public License
  30.  *  along with this program; if not, write to the Free Software
  31.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  32.  */
  33.  
  34. /*
  35.  *  Changes from version 1.1 to 1.2:
  36.  *    - compute_new_v() uses a 32 point fast cosine transform as described by
  37.  *      Byeong Gi Lee in IEEE Transactions ASSP-32 Part 2, August 1984,
  38.  *      "A New Algorithm to Compute the Discrete Cosine Transform"
  39.  *      instead of the matrix-vector multiplication in V1.1
  40.  *    - loop unrolling done in compute_pcm_samples()
  41.  *    - if ULAW is defined, the synthesis filter does a downsampling
  42.  *      to 8 kHz by dropping samples and ignoring subbands above 4 kHz
  43.  */
  44.  
  45.  
  46. #ifdef __WIN32__
  47. #define STRICT
  48. #include <windows.h>
  49. #endif // __WIN32__
  50.  
  51. #include <math.h>
  52. #include "all.h"
  53. #include "synfilt.h"
  54.  
  55. static const real MY_PI = 3.14159265358979323846;
  56.  
  57. static const real cos1_64  = 1.0 / (2.0 * cos(MY_PI        / 64.0));
  58. static const real cos3_64  = 1.0 / (2.0 * cos(MY_PI * 3.0  / 64.0));
  59. static const real cos5_64  = 1.0 / (2.0 * cos(MY_PI * 5.0  / 64.0));
  60. static const real cos7_64  = 1.0 / (2.0 * cos(MY_PI * 7.0  / 64.0));
  61. static const real cos9_64  = 1.0 / (2.0 * cos(MY_PI * 9.0  / 64.0));
  62. static const real cos11_64 = 1.0 / (2.0 * cos(MY_PI * 11.0 / 64.0));
  63. static const real cos13_64 = 1.0 / (2.0 * cos(MY_PI * 13.0 / 64.0));
  64. static const real cos15_64 = 1.0 / (2.0 * cos(MY_PI * 15.0 / 64.0));
  65. static const real cos17_64 = 1.0 / (2.0 * cos(MY_PI * 17.0 / 64.0));
  66. static const real cos19_64 = 1.0 / (2.0 * cos(MY_PI * 19.0 / 64.0));
  67. static const real cos21_64 = 1.0 / (2.0 * cos(MY_PI * 21.0 / 64.0));
  68. static const real cos23_64 = 1.0 / (2.0 * cos(MY_PI * 23.0 / 64.0));
  69. static const real cos25_64 = 1.0 / (2.0 * cos(MY_PI * 25.0 / 64.0));
  70. static const real cos27_64 = 1.0 / (2.0 * cos(MY_PI * 27.0 / 64.0));
  71. static const real cos29_64 = 1.0 / (2.0 * cos(MY_PI * 29.0 / 64.0));
  72. static const real cos31_64 = 1.0 / (2.0 * cos(MY_PI * 31.0 / 64.0));
  73. static const real cos1_32  = 1.0 / (2.0 * cos(MY_PI        / 32.0));
  74. static const real cos3_32  = 1.0 / (2.0 * cos(MY_PI * 3.0  / 32.0));
  75. static const real cos5_32  = 1.0 / (2.0 * cos(MY_PI * 5.0  / 32.0));
  76. static const real cos7_32  = 1.0 / (2.0 * cos(MY_PI * 7.0  / 32.0));
  77. static const real cos9_32  = 1.0 / (2.0 * cos(MY_PI * 9.0  / 32.0));
  78. static const real cos11_32 = 1.0 / (2.0 * cos(MY_PI * 11.0 / 32.0));
  79. static const real cos13_32 = 1.0 / (2.0 * cos(MY_PI * 13.0 / 32.0));
  80. static const real cos15_32 = 1.0 / (2.0 * cos(MY_PI * 15.0 / 32.0));
  81. static const real cos1_16  = 1.0 / (2.0 * cos(MY_PI        / 16.0));
  82. static const real cos3_16  = 1.0 / (2.0 * cos(MY_PI * 3.0  / 16.0));
  83. static const real cos5_16  = 1.0 / (2.0 * cos(MY_PI * 5.0  / 16.0));
  84. static const real cos7_16  = 1.0 / (2.0 * cos(MY_PI * 7.0  / 16.0));
  85. static const real cos1_8   = 1.0 / (2.0 * cos(MY_PI        / 8.0));
  86. static const real cos3_8   = 1.0 / (2.0 * cos(MY_PI * 3.0  / 8.0));
  87. static const real cos1_4   = 1.0 / (2.0 * cos(MY_PI / 4.0));
  88.  
  89.  
  90. const real SynthesisFilter::d[512] = {
  91.     // Note: These values are not in the same order
  92.     // as in Annex 3-B.3 of the ISO/IEC DIS 11172-3
  93.     0.000000000, -0.000442505,  0.003250122, -0.007003784,
  94.     0.031082153, -0.078628540,  0.100311279, -0.572036743,
  95.     1.144989014,  0.572036743,  0.100311279,  0.078628540,
  96.     0.031082153,  0.007003784,  0.003250122,  0.000442505,
  97.     -0.000015259, -0.000473022,  0.003326416, -0.007919312,
  98.     0.030517578, -0.084182739,  0.090927124, -0.600219727,
  99.     1.144287109,  0.543823242,  0.108856201,  0.073059082,
  100.     0.031478882,  0.006118774,  0.003173828,  0.000396729,
  101.   -0.000015259, -0.000534058,  0.003387451, -0.008865356,
  102.     0.029785156, -0.089706421,  0.080688477, -0.628295898,
  103.     1.142211914,  0.515609741,  0.116577148,  0.067520142,
  104.      0.031738281,  0.005294800,  0.003082275,  0.000366211,
  105.     -0.000015259, -0.000579834,  0.003433228, -0.009841919,
  106.      0.028884888, -0.095169067,  0.069595337, -0.656219482,
  107.     1.138763428,  0.487472534,  0.123474121,  0.061996460,
  108.    0.031845093,  0.004486084,  0.002990723,  0.000320435,
  109.   -0.000015259, -0.000625610,  0.003463745, -0.010848999,
  110.      0.027801514, -0.100540161,  0.057617188, -0.683914185,
  111.     1.133926392,  0.459472656,  0.129577637,  0.056533813,
  112.     0.031814575,  0.003723145,  0.002899170,  0.000289917,
  113.   -0.000015259, -0.000686646,  0.003479004, -0.011886597,
  114.     0.026535034, -0.105819702,  0.044784546, -0.711318970,
  115.     1.127746582,  0.431655884,  0.134887695,  0.051132202,
  116.     0.031661987,  0.003005981,  0.002792358,  0.000259399,
  117.     -0.000015259, -0.000747681,  0.003479004, -0.012939453,
  118.     0.025085449, -0.110946655,  0.031082153, -0.738372803,
  119.    1.120223999,  0.404083252,  0.139450073,  0.045837402,
  120.    0.031387329,  0.002334595,  0.002685547,  0.000244141,
  121.   -0.000030518, -0.000808716,  0.003463745, -0.014022827,
  122.    0.023422241, -0.115921021,  0.016510010, -0.765029907,
  123.     1.111373901,  0.376800537,  0.143264771,  0.040634155,
  124.    0.031005859,  0.001693726,  0.002578735,  0.000213623,
  125.     -0.000030518, -0.000885010,  0.003417969, -0.015121460,
  126.     0.021575928, -0.120697021,  0.001068115, -0.791213989,
  127.    1.101211548,  0.349868774,  0.146362305,  0.035552979,
  128.     0.030532837,  0.001098633,  0.002456665,  0.000198364,
  129.     -0.000030518, -0.000961304,  0.003372192, -0.016235352,
  130.    0.019531250, -0.125259399, -0.015228271, -0.816864014,
  131.      1.089782715,  0.323318481,  0.148773193,  0.030609131,
  132.     0.029937744,  0.000549316,  0.002349854,  0.000167847,
  133.     -0.000030518, -0.001037598,  0.003280640, -0.017349243,
  134.     0.017257690, -0.129562378, -0.032379150, -0.841949463,
  135.    1.077117920,  0.297210693,  0.150497437,  0.025817871,
  136.    0.029281616,  0.000030518,  0.002243042,  0.000152588,
  137.   -0.000045776, -0.001113892,  0.003173828, -0.018463135,
  138.     0.014801025, -0.133590698, -0.050354004, -0.866363525,
  139.     1.063217163,  0.271591187,  0.151596069,  0.021179199,
  140.     0.028533936, -0.000442505,  0.002120972,  0.000137329,
  141.     -0.000045776, -0.001205444,  0.003051758, -0.019577026,
  142.     0.012115479, -0.137298584, -0.069168091, -0.890090942,
  143.      1.048156738,  0.246505737,  0.152069092,  0.016708374,
  144.     0.027725220, -0.000869751,  0.002014160,  0.000122070,
  145.   -0.000061035, -0.001296997,  0.002883911, -0.020690918,
  146.    0.009231567, -0.140670776, -0.088775635, -0.913055420,
  147.      1.031936646,  0.221984863,  0.151962280,  0.012420654,
  148.    0.026840210, -0.001266479,  0.001907349,  0.000106812,
  149.   -0.000061035, -0.001388550,  0.002700806, -0.021789551,
  150.     0.006134033, -0.143676758, -0.109161377, -0.935195923,
  151.    1.014617920,  0.198059082,  0.151306152,  0.008316040,
  152.     0.025909424, -0.001617432,  0.001785278,  0.000106812,
  153.     -0.000076294, -0.001480103,  0.002487183, -0.022857666,
  154.      0.002822876, -0.146255493, -0.130310059, -0.956481934,
  155.     0.996246338,  0.174789429,  0.150115967,  0.004394531,
  156.    0.024932861, -0.001937866,  0.001693726,  0.000091553,
  157.   -0.000076294, -0.001586914,  0.002227783, -0.023910522,
  158.     -0.000686646, -0.148422241, -0.152206421, -0.976852417,
  159.    0.976852417,  0.152206421,  0.148422241,  0.000686646,
  160.     0.023910522, -0.002227783,  0.001586914,  0.000076294,
  161.     -0.000091553, -0.001693726,  0.001937866, -0.024932861,
  162.     -0.004394531, -0.150115967, -0.174789429, -0.996246338,
  163.    0.956481934,  0.130310059,  0.146255493, -0.002822876,
  164.    0.022857666, -0.002487183,  0.001480103,  0.000076294,
  165.     -0.000106812, -0.001785278,  0.001617432, -0.025909424,
  166.   -0.008316040, -0.151306152, -0.198059082, -1.014617920,
  167.    0.935195923,  0.109161377,  0.143676758, -0.006134033,
  168.    0.021789551, -0.002700806,  0.001388550,  0.000061035,
  169.   -0.000106812, -0.001907349,  0.001266479, -0.026840210,
  170.     -0.012420654, -0.151962280, -0.221984863, -1.031936646,
  171.     0.913055420,  0.088775635,  0.140670776, -0.009231567,
  172.      0.020690918, -0.002883911,  0.001296997,  0.000061035,
  173.     -0.000122070, -0.002014160,  0.000869751, -0.027725220,
  174.   -0.016708374, -0.152069092, -0.246505737, -1.048156738,
  175.    0.890090942,  0.069168091,  0.137298584, -0.012115479,
  176.     0.019577026, -0.003051758,  0.001205444,  0.000045776,
  177.     -0.000137329, -0.002120972,  0.000442505, -0.028533936,
  178.   -0.021179199, -0.151596069, -0.271591187, -1.063217163,
  179.    0.866363525,  0.050354004,  0.133590698, -0.014801025,
  180.    0.018463135, -0.003173828,  0.001113892,  0.000045776,
  181.   -0.000152588, -0.002243042, -0.000030518, -0.029281616,
  182.   -0.025817871, -0.150497437, -0.297210693, -1.077117920,
  183.      0.841949463,  0.032379150,  0.129562378, -0.017257690,
  184.      0.017349243, -0.003280640,  0.001037598,  0.000030518,
  185.   -0.000167847, -0.002349854, -0.000549316, -0.029937744,
  186.   -0.030609131, -0.148773193, -0.323318481, -1.089782715,
  187.     0.816864014,  0.015228271,  0.125259399, -0.019531250,
  188.    0.016235352, -0.003372192,  0.000961304,  0.000030518,
  189.     -0.000198364, -0.002456665, -0.001098633, -0.030532837,
  190.     -0.035552979, -0.146362305, -0.349868774, -1.101211548,
  191.      0.791213989, -0.001068115,  0.120697021, -0.021575928,
  192.     0.015121460, -0.003417969,  0.000885010,  0.000030518,
  193.   -0.000213623, -0.002578735, -0.001693726, -0.031005859,
  194.     -0.040634155, -0.143264771, -0.376800537, -1.111373901,
  195.    0.765029907, -0.016510010,  0.115921021, -0.023422241,
  196.    0.014022827, -0.003463745,  0.000808716,  0.000030518,
  197.   -0.000244141, -0.002685547, -0.002334595, -0.031387329,
  198.   -0.045837402, -0.139450073, -0.404083252, -1.120223999,
  199.    0.738372803, -0.031082153,  0.110946655, -0.025085449,
  200.     0.012939453, -0.003479004,  0.000747681,  0.000015259,
  201.     -0.000259399, -0.002792358, -0.003005981, -0.031661987,
  202.   -0.051132202, -0.134887695, -0.431655884, -1.127746582,
  203.     0.711318970, -0.044784546,  0.105819702, -0.026535034,
  204.    0.011886597, -0.003479004,  0.000686646,  0.000015259,
  205.     -0.000289917, -0.002899170, -0.003723145, -0.031814575,
  206.     -0.056533813, -0.129577637, -0.459472656, -1.133926392,
  207.    0.683914185, -0.057617188,  0.100540161, -0.027801514,
  208.     0.010848999, -0.003463745,  0.000625610,  0.000015259,
  209.   -0.000320435, -0.002990723, -0.004486084, -0.031845093,
  210.   -0.061996460, -0.123474121, -0.487472534, -1.138763428,
  211.     0.656219482, -0.069595337,  0.095169067, -0.028884888,
  212.     0.009841919, -0.003433228,  0.000579834,  0.000015259,
  213.     -0.000366211, -0.003082275, -0.005294800, -0.031738281,
  214.   -0.067520142, -0.116577148, -0.515609741, -1.142211914,
  215.     0.628295898, -0.080688477,  0.089706421, -0.029785156,
  216.     0.008865356, -0.003387451,  0.000534058,  0.000015259,
  217.   -0.000396729, -0.003173828, -0.006118774, -0.031478882,
  218.   -0.073059082, -0.108856201, -0.543823242, -1.144287109,
  219.     0.600219727, -0.090927124,  0.084182739, -0.030517578,
  220.     0.007919312, -0.003326416,  0.000473022,  0.000015259
  221. };
  222.  
  223. SynthesisFilter::SynthesisFilter(uint32 channelnumber, real factor)
  224. {
  225.     register real *floatp, *floatp2;
  226.  
  227.   // initialize v1[] and v2[]:
  228.     for (floatp = v1 + 512, floatp2 = v2 + 512; floatp > v1; )
  229.      *--floatp = *--floatp2 = 0.0;
  230.  
  231.   // initialize samples[]:
  232.   for (floatp = samples + 32; floatp > samples; )
  233.      *--floatp = 0.0;
  234.  
  235.   channel = channelnumber;
  236.     range_violations = written_samples = 0;
  237.     actual_v = v1;
  238.   actual_write_pos = 15;
  239.   scalefactor = factor;
  240. }
  241.  
  242.  
  243. void SynthesisFilter::compute_new_v()
  244. {
  245.     real new_v[32];         // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3
  246.     real p[16];
  247.     real pp[16];
  248.  
  249.     // compute new values via a fast cosine transform:
  250.     {
  251.     register real *x1 = samples;
  252.  
  253.     p[0] = x1[0] + x1[31];
  254.     p[1] = x1[1] + x1[30];
  255.     p[2] = x1[2] + x1[29];
  256.     p[3] = x1[3] + x1[28];
  257.     p[4] = x1[4] + x1[27];
  258.     p[5] = x1[5] + x1[26];
  259.     p[6] = x1[6] + x1[25];
  260.     p[7] = x1[7] + x1[24];
  261.     p[8] = x1[8] + x1[23];
  262.     p[9] = x1[9] + x1[22];
  263.     p[10] = x1[10] + x1[21];
  264.     p[11] = x1[11] + x1[20];
  265.     p[12] = x1[12] + x1[19];
  266.     p[13] = x1[13] + x1[18];
  267.     p[14] = x1[14] + x1[17];
  268.     p[15] = x1[15] + x1[16];
  269.     }
  270.  
  271.     {
  272.     pp[0] = p[0] + p[15];
  273.     pp[1] = p[1] + p[14];
  274.     pp[2] = p[2] + p[13];
  275.     pp[3] = p[3] + p[12];
  276.     pp[4] = p[4] + p[11];
  277.     pp[5] = p[5] + p[10];
  278.     pp[6] = p[6] + p[9];
  279.     pp[7] = p[7] + p[8];
  280.     pp[8] = (p[0] - p[15]) * cos1_32;
  281.     pp[9] = (p[1] - p[14]) * cos3_32;
  282.     pp[10] = (p[2] - p[13]) * cos5_32;
  283.     pp[11] = (p[3] - p[12]) * cos7_32;
  284.     pp[12] = (p[4] - p[11]) * cos9_32;
  285.     pp[13] = (p[5] - p[10]) * cos11_32;
  286.     pp[14] = (p[6] - p[9]) * cos13_32;
  287.     pp[15] = (p[7] - p[8]) * cos15_32;
  288.     }
  289.  
  290.     {
  291.     p[0] = pp[0] + pp[7];
  292.     p[1] = pp[1] + pp[6];
  293.     p[2] = pp[2] + pp[5];
  294.     p[3] = pp[3] + pp[4];
  295.     p[4] = (pp[0] - pp[7]) * cos1_16;
  296.     p[5] = (pp[1] - pp[6]) * cos3_16;
  297.     p[6] = (pp[2] - pp[5]) * cos5_16;
  298.     p[7] = (pp[3] - pp[4]) * cos7_16;
  299.     p[8] = pp[8] + pp[15];
  300.     p[9] = pp[9] + pp[14];
  301.     p[10] = pp[10] + pp[13];
  302.     p[11] = pp[11] + pp[12];
  303.     p[12] = (pp[8] - pp[15]) * cos1_16;
  304.     p[13] = (pp[9] - pp[14]) * cos3_16;
  305.     p[14] = (pp[10] - pp[13]) * cos5_16;
  306.     p[15] = (pp[11] - pp[12]) * cos7_16;
  307.     }
  308.  
  309.     {
  310.     pp[0] = p[0] + p[3];
  311.     pp[1] = p[1] + p[2];
  312.     pp[2] = (p[0] - p[3]) * cos1_8;
  313.     pp[3] = (p[1] - p[2]) * cos3_8;
  314.     pp[4] = p[4] + p[7];
  315.     pp[5] = p[5] + p[6];
  316.     pp[6] = (p[4] - p[7]) * cos1_8;
  317.     pp[7] = (p[5] - p[6]) * cos3_8;
  318.     pp[8] = p[8] + p[11];
  319.     pp[9] = p[9] + p[10];
  320.     pp[10] = (p[8] - p[11]) * cos1_8;
  321.     pp[11] = (p[9] - p[10]) * cos3_8;
  322.     pp[12] = p[12] + p[15];
  323.     pp[13] = p[13] + p[14];
  324.     pp[14] = (p[12] - p[15]) * cos1_8;
  325.     pp[15] = (p[13] - p[14]) * cos3_8;
  326.     }
  327.  
  328.     {
  329.     p[0] = pp[0] + pp[1];
  330.     p[1] = (pp[0] - pp[1]) * cos1_4;
  331.     p[2] = pp[2] + pp[3];
  332.     p[3] = (pp[2] - pp[3]) * cos1_4;
  333.     p[4] = pp[4] + pp[5];
  334.     p[5] = (pp[4] - pp[5]) * cos1_4;
  335.     p[6] = pp[6] + pp[7];
  336.     p[7] = (pp[6] - pp[7]) * cos1_4;
  337.     p[8] = pp[8] + pp[9];
  338.     p[9] = (pp[8] - pp[9]) * cos1_4;
  339.     p[10] = pp[10] + pp[11];
  340.     p[11] = (pp[10] - pp[11]) * cos1_4;
  341.     p[12] = pp[12] + pp[13];
  342.     p[13] = (pp[12] - pp[13]) * cos1_4;
  343.     p[14] = pp[14] + pp[15];
  344.     p[15] = (pp[14] - pp[15]) * cos1_4;
  345.     }
  346.  
  347.  
  348. /*
  349.      The Borland C/C++ compiler, up to version 4.52 at least, will not find
  350.      common subexpressions for floating point code under 32-bit compilation.
  351.      The result is that this is manually done, although the original code is
  352.      maintained to revert to a more 'prettier' form when the compiler improves.
  353. // if the compiler does seem to want to grab common subexpressions, we
  354. //    could then manually do it
  355.     {
  356.     new_v[12]    = p[7];
  357.     new_v[4]     = p[7] + p[5];
  358.     new_v[36-17] = -p[6] - p[7] - p[5];
  359.     new_v[44-17] = -p[6] - p[7] - p[4];
  360.     new_v[14]    = p[15];
  361.     new_v[10]    = p[11] + p[15];
  362.     new_v[6]     = p[11] + p[15] + p[13];
  363.     new_v[2]     = p[15] + p[13] + p[9];
  364.     new_v[34-17] = -p[14] - p[15] - p[13] - p[9];
  365.     new_v[38-17] = -p[14] - p[15] - p[13] - p[10] - p[11];
  366.     new_v[46-17] = -p[14] - p[15] - p[12] - p[8];
  367.     new_v[42-17] = -p[14] - p[15] - p[12] - p[10] - p[11];
  368.     new_v[48-17] = -p[0];
  369.     new_v[0]     = p[1];
  370.     new_v[8]     = p[3];
  371.     new_v[40-17] = -p[3] - p[2];
  372.     }
  373.  */
  374.     {
  375.     // this is pretty insane coding
  376.     register real tmp1;
  377.     new_v[36-17] = -(new_v[4] = (new_v[12] = p[7]) + p[5]) - p[6];
  378.     new_v[44-17] = -p[6] - p[7] - p[4];
  379.     new_v[6] = (new_v[10] = (new_v[14] = p[15]) + p[11]) + p[13];
  380.     new_v[34-17] = -(new_v[2] = p[15] + p[13] + p[9]) - p[14];
  381.     new_v[38-17] = (tmp1 = -p[14] - p[15] - p[10] - p[11]) - p[13];
  382.     new_v[46-17] = -p[14] - p[15] - p[12] - p[8];
  383.     new_v[42-17] = tmp1 - p[12];
  384.     new_v[48-17] = -p[0];
  385.     new_v[0] = p[1];
  386.     new_v[40-17] = -(new_v[8] = p[3]) - p[2];
  387.     }
  388.  
  389.     {
  390.     register real *x1 = samples;
  391.  
  392.     p[0] = (x1[0] - x1[31]) * cos1_64;
  393.     p[1] = (x1[1] - x1[30]) * cos3_64;
  394.     p[2] = (x1[2] - x1[29]) * cos5_64;
  395.     p[3] = (x1[3] - x1[28]) * cos7_64;
  396.     p[4] = (x1[4] - x1[27]) * cos9_64;
  397.     p[5] = (x1[5] - x1[26]) * cos11_64;
  398.     p[6] = (x1[6] - x1[25]) * cos13_64;
  399.     p[7] = (x1[7] - x1[24]) * cos15_64;
  400.     p[8] = (x1[8] - x1[23]) * cos17_64;
  401.     p[9] = (x1[9] - x1[22]) * cos19_64;
  402.     p[10] = (x1[10] - x1[21]) * cos21_64;
  403.     p[11] = (x1[11] - x1[20]) * cos23_64;
  404.     p[12] = (x1[12] - x1[19]) * cos25_64;
  405.     p[13] = (x1[13] - x1[18]) * cos27_64;
  406.     p[14] = (x1[14] - x1[17]) * cos29_64;
  407.     p[15] = (x1[15] - x1[16]) * cos31_64;
  408.     }
  409.  
  410.     {
  411.     pp[0] = p[0] + p[15];
  412.     pp[1] = p[1] + p[14];
  413.     pp[2] = p[2] + p[13];
  414.     pp[3] = p[3] + p[12];
  415.     pp[4] = p[4] + p[11];
  416.     pp[5] = p[5] + p[10];
  417.     pp[6] = p[6] + p[9];
  418.     pp[7] = p[7] + p[8];
  419.     pp[8] = (p[0] - p[15]) * cos1_32;
  420.     pp[9] = (p[1] - p[14]) * cos3_32;
  421.     pp[10] = (p[2] - p[13]) * cos5_32;
  422.     pp[11] = (p[3] - p[12]) * cos7_32;
  423.     pp[12] = (p[4] - p[11]) * cos9_32;
  424.     pp[13] = (p[5] - p[10]) * cos11_32;
  425.     pp[14] = (p[6] - p[9]) * cos13_32;
  426.     pp[15] = (p[7] - p[8]) * cos15_32;
  427.     }
  428.  
  429.     {
  430.     p[0] = pp[0] + pp[7];
  431.     p[1] = pp[1] + pp[6];
  432.     p[2] = pp[2] + pp[5];
  433.     p[3] = pp[3] + pp[4];
  434.     p[4] = (pp[0] - pp[7]) * cos1_16;
  435.     p[5] = (pp[1] - pp[6]) * cos3_16;
  436.     p[6] = (pp[2] - pp[5]) * cos5_16;
  437.     p[7] = (pp[3] - pp[4]) * cos7_16;
  438.     p[8] = pp[8] + pp[15];
  439.     p[9] = pp[9] + pp[14];
  440.     p[10] = pp[10] + pp[13];
  441.     p[11] = pp[11] + pp[12];
  442.     p[12] = (pp[8] - pp[15]) * cos1_16;
  443.     p[13] = (pp[9] - pp[14]) * cos3_16;
  444.     p[14] = (pp[10] - pp[13]) * cos5_16;
  445.     p[15] = (pp[11] - pp[12]) * cos7_16;
  446.     }
  447.  
  448.     {
  449.     pp[0] = p[0] + p[3];
  450.     pp[1] = p[1] + p[2];
  451.     pp[2] = (p[0] - p[3]) * cos1_8;
  452.     pp[3] = (p[1] - p[2]) * cos3_8;
  453.     pp[4] = p[4] + p[7];
  454.     pp[5] = p[5] + p[6];
  455.     pp[6] = (p[4] - p[7]) * cos1_8;
  456.     pp[7] = (p[5] - p[6]) * cos3_8;
  457.     pp[8] = p[8] + p[11];
  458.     pp[9] = p[9] + p[10];
  459.     pp[10] = (p[8] - p[11]) * cos1_8;
  460.     pp[11] = (p[9] - p[10]) * cos3_8;
  461.     pp[12] = p[12] + p[15];
  462.     pp[13] = p[13] + p[14];
  463.     pp[14] = (p[12] - p[15]) * cos1_8;
  464.     pp[15] = (p[13] - p[14]) * cos3_8;
  465.     }
  466.  
  467.     {
  468.     p[0] = pp[0] + pp[1];
  469.     p[1] = (pp[0] - pp[1]) * cos1_4;
  470.     p[2] = pp[2] + pp[3];
  471.     p[3] = (pp[2] - pp[3]) * cos1_4;
  472.     p[4] = pp[4] + pp[5];
  473.     p[5] = (pp[4] - pp[5]) * cos1_4;
  474.     p[6] = pp[6] + pp[7];
  475.     p[7] = (pp[6] - pp[7]) * cos1_4;
  476.     p[8] = pp[8] + pp[9];
  477.     p[9] = (pp[8] - pp[9]) * cos1_4;
  478.     p[10] = pp[10] + pp[11];
  479.     p[11] = (pp[10] - pp[11]) * cos1_4;
  480.     p[12] = pp[12] + pp[13];
  481.     p[13] = (pp[12] - pp[13]) * cos1_4;
  482.     p[14] = pp[14] + pp[15];
  483.     p[15] = (pp[14] - pp[15]) * cos1_4;
  484.     }
  485.  
  486. /*
  487.      The Borland C/C++ compiler, up to version 4.52 at least, will not find
  488.      common subexpressions for floating point code under 32-bit compilation.
  489.      The result is that this is manually done, although the original code is
  490.      maintained to revert to a more 'prettier' form when the compiler improves.
  491. // if the compiler does seem to want to grab common subexpressions, we
  492. //    could then manually do it
  493.     {
  494.     new_v[15]    = p[15];
  495.     new_v[13]    = p[15] + p[7];
  496.     new_v[11]    = p[15] + p[7] + p[11];
  497.     new_v[5]     = p[15] + p[7] + p[11] + p[5] + p[13];
  498.     new_v[9]     = p[15] + p[11] + p[3];
  499.     new_v[7]     = p[15] + p[11] + p[3] + p[13];
  500.     new_v[1]     = p[13] + p[15] + p[9] + p[1];
  501.     new_v[33-17] = -p[13] - p[15] - p[9] - p[1] - p[14];
  502.     new_v[3]     = p[13] + p[15] + p[9] + p[5] + p[7];
  503.     new_v[35-17] = -p[13] - p[15] - p[9] - p[5] - p[7] - p[6] - p[14];
  504.     new_v[39-17] = p[12] - p[10] - p[11] - p[12] - p[13] - p[14] - p[15]
  505.                         - p[2] - p[3];
  506.     new_v[37-17] = p[12] - p[10] - p[11] - p[12] - p[13] - p[14] - p[15]
  507.                         - p[5] - p[6] - p[7];
  508.     new_v[43-17] = p[13] - p[10] - p[11] - p[12] - p[13] - p[14] - p[15]
  509.                         - p[4] - p[6] - p[7];
  510.     new_v[41-17] = p[13] - p[10] - p[11] - p[12] - p[13] - p[14] - p[15]
  511.                         - p[2] - p[3];
  512.     new_v[47-17] = -p[8] - p[12] - p[14] - p[15] - p[0];
  513.     new_v[45-17] = -p[8] - p[12] - p[14] - p[15] - p[4] - p[6] - p[7];
  514.     }
  515. */
  516.  
  517.     {
  518.     // manually doing something that a compiler should handle sucks
  519.     // coding like this is hard to read
  520.     register real tmp1, tmp2;
  521.     new_v[5] = (new_v[11] = (new_v[13] = (new_v[15] = p[15]) + p[7]) + p[11])
  522.                             + p[5] + p[13];
  523.     new_v[7] = (new_v[9] = p[15] + p[11] + p[3]) + p[13];
  524.     new_v[33-17] = -(new_v[1] = (tmp1 = p[13] + p[15] + p[9]) + p[1]) - p[14];
  525.     new_v[35-17] = -(new_v[3] = tmp1 + p[5] + p[7]) - p[6] - p[14];
  526.  
  527.     new_v[39-17] = (tmp1 = -p[10] - p[11] - p[14] - p[15])
  528.                                     - p[13] - p[2] - p[3];
  529.     new_v[37-17] = tmp1 - p[13] - p[5] - p[6] - p[7];
  530.     new_v[41-17] = tmp1 - p[12] - p[2] - p[3];
  531.     new_v[43-17] = tmp1 - p[12] - (tmp2 = p[4] + p[6] + p[7]);
  532.     new_v[47-17] = (tmp1 = -p[8] - p[12] - p[14] - p[15]) - p[0];
  533.     new_v[45-17] = tmp1 - tmp2;
  534.     }
  535.  
  536.     {
  537.     // insert V[0-15] (== new_v[0-15]) into actual v:
  538.     register real *x1 = new_v;
  539.     register real *x2 = actual_v + actual_write_pos;
  540.     x2[0] = x1[0];
  541.     x2[16] = x1[1];
  542.     x2[32] = x1[2];
  543.     x2[48] = x1[3];
  544.     x2[64] = x1[4];
  545.     x2[80] = x1[5];
  546.     x2[96] = x1[6];
  547.     x2[112] = x1[7];
  548.     x2[128] = x1[8];
  549.     x2[144] = x1[9];
  550.     x2[160] = x1[10];
  551.     x2[176] = x1[11];
  552.     x2[192] = x1[12];
  553.     x2[208] = x1[13];
  554.     x2[224] = x1[14];
  555.     x2[240] = x1[15];
  556.  
  557.     // V[16] is always 0.0:
  558.     x2[256] = 0.0;
  559.  
  560.     // insert V[17-31] (== -new_v[15-1]) into actual v:
  561.     x2[272] = -x1[15];
  562.     x2[288] = -x1[14];
  563.     x2[304] = -x1[13];
  564.     x2[320] = -x1[12];
  565.     x2[336] = -x1[11];
  566.     x2[352] = -x1[10];
  567.     x2[368] = -x1[9];
  568.     x2[384] = -x1[8];
  569.     x2[400] = -x1[7];
  570.     x2[416] = -x1[6];
  571.     x2[432] = -x1[5];
  572.     x2[448] = -x1[4];
  573.     x2[464] = -x1[3];
  574.     x2[480] = -x1[2];
  575.     x2[496] = -x1[1];
  576.  
  577.     // insert V[32] (== -new_v[0]) into other v:
  578.     x2 = (actual_v == v1 ? v2 : v1) + actual_write_pos;
  579.     x2[0] = -x1[0];
  580.  
  581.     // insert V[33-48] (== new_v[16-31]) into other v:
  582.     x2[16] = x1[16];
  583.     x2[32] = x1[17];
  584.     x2[48] = x1[18];
  585.     x2[64] = x1[19];
  586.     x2[80] = x1[20];
  587.     x2[96] = x1[21];
  588.     x2[112] = x1[22];
  589.     x2[128] = x1[23];
  590.     x2[144] = x1[24];
  591.     x2[160] = x1[25];
  592.     x2[176] = x1[26];
  593.     x2[192] = x1[27];
  594.     x2[208] = x1[28];
  595.     x2[224] = x1[29];
  596.     x2[240] = x1[30];
  597.     x2[256] = x1[31];
  598.  
  599.     // insert V[49-63] (== new_v[30-16]) into other v:
  600.     x2[272] = x1[30];
  601.     x2[288] = x1[29];
  602.     x2[304] = x1[28];
  603.     x2[320] = x1[27];
  604.     x2[336] = x1[26];
  605.     x2[352] = x1[25];
  606.     x2[368] = x1[24];
  607.     x2[384] = x1[23];
  608.     x2[400] = x1[22];
  609.     x2[416] = x1[21];
  610.     x2[432] = x1[20];
  611.     x2[448] = x1[19];
  612.     x2[464] = x1[18];
  613.     x2[480] = x1[17];
  614.     x2[496] = x1[16];
  615.     }
  616. }
  617.  
  618. void SynthesisFilter::compute_pcm_samples(Obuffer *buffer)
  619. {
  620.     // scoping variables makes it easier to optimize for the compiler
  621.     register real *vp = actual_v;
  622.  
  623.     // switch depending on the value for actual_write_pos
  624.     switch( actual_write_pos ) {
  625.         case 0: {
  626.             // fat chance of having this loop unroll
  627.             for( register const real *dp = d;
  628.                      dp < d + (32 * 16);
  629.                      dp += 16, vp += 16 ) {
  630.                 register int32 pcm_sample;
  631.  
  632.                 pcm_sample = (int32)(((vp[0] * dp[0]) +
  633.                     (vp[15] * dp[1]) +
  634.                     (vp[14] * dp[2]) +
  635.                     (vp[13] * dp[3]) +
  636.                     (vp[12] * dp[4]) +
  637.                     (vp[11] * dp[5]) +
  638.                     (vp[10] * dp[6]) +
  639.                     (vp[9] * dp[7]) +
  640.                     (vp[8] * dp[8]) +
  641.                     (vp[7] * dp[9]) +
  642.                     (vp[6] * dp[10]) +
  643.                     (vp[5] * dp[11]) +
  644.                     (vp[4] * dp[12]) +
  645.                     (vp[3] * dp[13]) +
  646.                     (vp[2] * dp[14]) +
  647.                     (vp[1] * dp[15])
  648.                     ) * scalefactor);
  649.  
  650.             buffer->append (channel, clip(pcm_sample));
  651.             } /* for */
  652.         } break; /* case 0: */
  653.  
  654.         case 1: {
  655.             // fat chance of having this loop unroll
  656.             for( register const real *dp = d;
  657.                      dp < d + (32 * 16);
  658.                      dp += 16, vp += 16 ) {
  659.                 register int32 pcm_sample;
  660.  
  661.                 pcm_sample = (int32)(((vp[1] * dp[0]) +
  662.                     (vp[0] * dp[1]) +
  663.                     (vp[15] * dp[2]) +
  664.                     (vp[14] * dp[3]) +
  665.                     (vp[13] * dp[4]) +
  666.                     (vp[12] * dp[5]) +
  667.                     (vp[11] * dp[6]) +
  668.                     (vp[10] * dp[7]) +
  669.                     (vp[9] * dp[8]) +
  670.                     (vp[8] * dp[9]) +
  671.                     (vp[7] * dp[10]) +
  672.                     (vp[6] * dp[11]) +
  673.                     (vp[5] * dp[12]) +
  674.                     (vp[4] * dp[13]) +
  675.                     (vp[3] * dp[14]) +
  676.                     (vp[2] * dp[15])
  677.                     ) * scalefactor);
  678.  
  679.             buffer->append (channel, clip(pcm_sample));
  680.          } /* for */
  681.         } break; /* case 1: */
  682.  
  683.         case 2: {
  684.             // fat chance of having this loop unroll
  685.             for( register const real *dp = d;
  686.                      dp < d + (32 * 16);
  687.                      dp += 16, vp += 16 ) {
  688.                 register int32 pcm_sample;
  689.  
  690.                 pcm_sample = (int32)(((vp[2] * dp[0]) +
  691.                     (vp[1] * dp[1]) +
  692.                     (vp[0] * dp[2]) +
  693.                     (vp[15] * dp[3]) +
  694.                     (vp[14] * dp[4]) +
  695.                     (vp[13] * dp[5]) +
  696.                     (vp[12] * dp[6]) +
  697.                     (vp[11] * dp[7]) +
  698.                     (vp[10] * dp[8]) +
  699.                     (vp[9] * dp[9]) +
  700.                     (vp[8] * dp[10]) +
  701.                     (vp[7] * dp[11]) +
  702.                     (vp[6] * dp[12]) +
  703.                     (vp[5] * dp[13]) +
  704.                     (vp[4] * dp[14]) +
  705.                     (vp[3] * dp[15])
  706.                     ) * scalefactor);
  707.  
  708.             buffer->append (channel, clip(pcm_sample));
  709.             } /* for */
  710.         } break; /* case 2: */
  711.  
  712.         case 3: {
  713.             // fat chance of having this loop unroll
  714.             for( register const real *dp = d;
  715.                      dp < d + (32 * 16);
  716.                      dp += 16, vp += 16 ) {
  717.                 register int32 pcm_sample;
  718.  
  719.                 pcm_sample = (int32)(((vp[3] * dp[0]) +
  720.                     (vp[2] * dp[1]) +
  721.                     (vp[1] * dp[2]) +
  722.                     (vp[0] * dp[3]) +
  723.                     (vp[15] * dp[4]) +
  724.                     (vp[14] * dp[5]) +
  725.                     (vp[13] * dp[6]) +
  726.                     (vp[12] * dp[7]) +
  727.                     (vp[11] * dp[8]) +
  728.                     (vp[10] * dp[9]) +
  729.                     (vp[9] * dp[10]) +
  730.                     (vp[8] * dp[11]) +
  731.                     (vp[7] * dp[12]) +
  732.                     (vp[6] * dp[13]) +
  733.                     (vp[5] * dp[14]) +
  734.                     (vp[4] * dp[15])
  735.                     ) * scalefactor);
  736.  
  737.                 buffer->append (channel, clip(pcm_sample));
  738.             } /* for */
  739.         } break; /* case 3: */
  740.  
  741.         case 4: {
  742.             // fat chance of having this loop unroll
  743.             for( register const real *dp = d;
  744.                      dp < d + (32 * 16);
  745.                      dp += 16, vp += 16 ) {
  746.                 register int32 pcm_sample;
  747.  
  748.                 pcm_sample = (int32)(((vp[4] * dp[0]) +
  749.                     (vp[3] * dp[1]) +
  750.                     (vp[2] * dp[2]) +
  751.                     (vp[1] * dp[3]) +
  752.                     (vp[0] * dp[4]) +
  753.                     (vp[15] * dp[5]) +
  754.                     (vp[14] * dp[6]) +
  755.                     (vp[13] * dp[7]) +
  756.                     (vp[12] * dp[8]) +
  757.                     (vp[11] * dp[9]) +
  758.                     (vp[10] * dp[10]) +
  759.                     (vp[9] * dp[11]) +
  760.                     (vp[8] * dp[12]) +
  761.                     (vp[7] * dp[13]) +
  762.                     (vp[6] * dp[14]) +
  763.                     (vp[5] * dp[15])
  764.                     ) * scalefactor);
  765.  
  766.                 buffer->append (channel, clip(pcm_sample));
  767.             } /* for */
  768.         } break; /* case 4: */
  769.  
  770.         case 5: {
  771.             // fat chance of having this loop unroll
  772.             for( register const real *dp = d;
  773.                      dp < d + (32 * 16);
  774.                      dp += 16, vp += 16 ) {
  775.                 register int32 pcm_sample;
  776.  
  777.                 pcm_sample = (int32)(((vp[5] * dp[0]) +
  778.                     (vp[4] * dp[1]) +
  779.                     (vp[3] * dp[2]) +
  780.                     (vp[2] * dp[3]) +
  781.                     (vp[1] * dp[4]) +
  782.                     (vp[0] * dp[5]) +
  783.                     (vp[15] * dp[6]) +
  784.                     (vp[14] * dp[7]) +
  785.                     (vp[13] * dp[8]) +
  786.                     (vp[12] * dp[9]) +
  787.                     (vp[11] * dp[10]) +
  788.                     (vp[10] * dp[11]) +
  789.                     (vp[9] * dp[12]) +
  790.                     (vp[8] * dp[13]) +
  791.                     (vp[7] * dp[14]) +
  792.                     (vp[6] * dp[15])
  793.                     ) * scalefactor);
  794.  
  795.                 buffer->append (channel, clip(pcm_sample));
  796.             } /* for */
  797.         } break; /* case 5: */
  798.  
  799.         case 6: {
  800.             // fat chance of having this loop unroll
  801.             for( register const real *dp = d;
  802.                      dp < d + (32 * 16);
  803.                      dp += 16, vp += 16 ) {
  804.                 register int32 pcm_sample;
  805.  
  806.                 pcm_sample = (int32)(((vp[6] * dp[0]) +
  807.                     (vp[5] * dp[1]) +
  808.                     (vp[4] * dp[2]) +
  809.                     (vp[3] * dp[3]) +
  810.                     (vp[2] * dp[4]) +
  811.                     (vp[1] * dp[5]) +
  812.                     (vp[0] * dp[6]) +
  813.                     (vp[15] * dp[7]) +
  814.                     (vp[14] * dp[8]) +
  815.                     (vp[13] * dp[9]) +
  816.                     (vp[12] * dp[10]) +
  817.                     (vp[11] * dp[11]) +
  818.                     (vp[10] * dp[12]) +
  819.                     (vp[9] * dp[13]) +
  820.                     (vp[8] * dp[14]) +
  821.                     (vp[7] * dp[15])
  822.                     ) * scalefactor);
  823.  
  824.             buffer->append (channel, clip(pcm_sample));
  825.             } /* for */
  826.         } break; /* case 6: */
  827.  
  828.         case 7: {
  829.             // fat chance of having this loop unroll
  830.             for( register const real *dp = d;
  831.                      dp < d + (32 * 16);
  832.                      dp += 16, vp += 16 ) {
  833.                 register int32 pcm_sample;
  834.  
  835.                 pcm_sample = (int32)(((vp[7] * dp[0]) +
  836.                     (vp[6] * dp[1]) +
  837.                     (vp[5] * dp[2]) +
  838.                     (vp[4] * dp[3]) +
  839.                     (vp[3] * dp[4]) +
  840.                     (vp[2] * dp[5]) +
  841.                     (vp[1] * dp[6]) +
  842.                     (vp[0] * dp[7]) +
  843.                     (vp[15] * dp[8]) +
  844.                     (vp[14] * dp[9]) +
  845.                     (vp[13] * dp[10]) +
  846.                     (vp[12] * dp[11]) +
  847.                     (vp[11] * dp[12]) +
  848.                     (vp[10] * dp[13]) +
  849.                     (vp[9] * dp[14]) +
  850.                     (vp[8] * dp[15])
  851.                     ) * scalefactor);
  852.  
  853.             buffer->append (channel, clip(pcm_sample));
  854.             } /* for */
  855.         } break; /* case 7: */
  856.  
  857.         case 8: {
  858.             // fat chance of having this loop unroll
  859.             for( register const real *dp = d;
  860.                      dp < d + (32 * 16);
  861.                      dp += 16, vp += 16 ) {
  862.                 register int32 pcm_sample;
  863.  
  864.                 pcm_sample = (int32)(((vp[8] * dp[0]) +
  865.                     (vp[7] * dp[1]) +
  866.                     (vp[6] * dp[2]) +
  867.                     (vp[5] * dp[3]) +
  868.                     (vp[4] * dp[4]) +
  869.                     (vp[3] * dp[5]) +
  870.                     (vp[2] * dp[6]) +
  871.                     (vp[1] * dp[7]) +
  872.                     (vp[0] * dp[8]) +
  873.                     (vp[15] * dp[9]) +
  874.                     (vp[14] * dp[10]) +
  875.                     (vp[13] * dp[11]) +
  876.                     (vp[12] * dp[12]) +
  877.                     (vp[11] * dp[13]) +
  878.                     (vp[10] * dp[14]) +
  879.                     (vp[9] * dp[15])
  880.                     ) * scalefactor);
  881.  
  882.             buffer->append (channel, clip(pcm_sample));
  883.             } /* for */
  884.         } break; /* case 8: */
  885.  
  886.         case 9: {
  887.             // fat chance of having this loop unroll
  888.             for( register const real *dp = d;
  889.                      dp < d + (32 * 16);
  890.                      dp += 16, vp += 16 ) {
  891.                 register int32 pcm_sample;
  892.  
  893.                 pcm_sample = (int32)(((vp[9] * dp[0]) +
  894.                     (vp[8] * dp[1]) +
  895.                     (vp[7] * dp[2]) +
  896.                     (vp[6] * dp[3]) +
  897.                     (vp[5] * dp[4]) +
  898.                     (vp[4] * dp[5]) +
  899.                     (vp[3] * dp[6]) +
  900.                     (vp[2] * dp[7]) +
  901.                     (vp[1] * dp[8]) +
  902.                     (vp[0] * dp[9]) +
  903.                     (vp[15] * dp[10]) +
  904.                     (vp[14] * dp[11]) +
  905.                     (vp[13] * dp[12]) +
  906.                     (vp[12] * dp[13]) +
  907.                     (vp[11] * dp[14]) +
  908.                     (vp[10] * dp[15])
  909.                     ) * scalefactor);
  910.  
  911.             buffer->append (channel, clip(pcm_sample));
  912.             } /* for */
  913.         } break; /* case 9: */
  914.  
  915.         case 10: {
  916.             // fat chance of having this loop unroll
  917.             for( register const real *dp = d;
  918.                      dp < d + (32 * 16);
  919.                      dp += 16, vp += 16 ) {
  920.                 register int32 pcm_sample;
  921.  
  922.                 pcm_sample = (int32)(((vp[10] * dp[0]) +
  923.                     (vp[9] * dp[1]) +
  924.                     (vp[8] * dp[2]) +
  925.                     (vp[7] * dp[3]) +
  926.                     (vp[6] * dp[4]) +
  927.                     (vp[5] * dp[5]) +
  928.                     (vp[4] * dp[6]) +
  929.                     (vp[3] * dp[7]) +
  930.                     (vp[2] * dp[8]) +
  931.                     (vp[1] * dp[9]) +
  932.                     (vp[0] * dp[10]) +
  933.                     (vp[15] * dp[11]) +
  934.                     (vp[14] * dp[12]) +
  935.                     (vp[13] * dp[13]) +
  936.                     (vp[12] * dp[14]) +
  937.                     (vp[11] * dp[15])
  938.                     ) * scalefactor);
  939.  
  940.             buffer->append (channel, clip(pcm_sample));
  941.             } /* for */
  942.         } break; /* case 10: */
  943.  
  944.         case 11: {
  945.             // fat chance of having this loop unroll
  946.             for( register const real *dp = d;
  947.                      dp < d + (32 * 16);
  948.                      dp += 16, vp += 16 ) {
  949.                 register int32 pcm_sample;
  950.  
  951.                 pcm_sample = (int32)(((vp[11] * dp[0]) +
  952.                     (vp[10] * dp[1]) +
  953.                     (vp[9] * dp[2]) +
  954.                     (vp[8] * dp[3]) +
  955.                     (vp[7] * dp[4]) +
  956.                     (vp[6] * dp[5]) +
  957.                     (vp[5] * dp[6]) +
  958.                     (vp[4] * dp[7]) +
  959.                     (vp[3] * dp[8]) +
  960.                     (vp[2] * dp[9]) +
  961.                     (vp[1] * dp[10]) +
  962.                     (vp[0] * dp[11]) +
  963.                     (vp[15] * dp[12]) +
  964.                     (vp[14] * dp[13]) +
  965.                     (vp[13] * dp[14]) +
  966.                     (vp[12] * dp[15])
  967.                     ) * scalefactor);
  968.  
  969.             buffer->append (channel, clip(pcm_sample));
  970.             } /* for */
  971.         } break; /* case 11: */
  972.  
  973.         case 12: {
  974.             // fat chance of having this loop unroll
  975.             for( register const real *dp = d;
  976.                      dp < d + (32 * 16);
  977.                      dp += 16, vp += 16 ) {
  978.                 register int32 pcm_sample;
  979.  
  980.                 pcm_sample = (int32)(((vp[12] * dp[0]) +
  981.                     (vp[11] * dp[1]) +
  982.                     (vp[10] * dp[2]) +
  983.                     (vp[9] * dp[3]) +
  984.                     (vp[8] * dp[4]) +
  985.                     (vp[7] * dp[5]) +
  986.                     (vp[6] * dp[6]) +
  987.                     (vp[5] * dp[7]) +
  988.                     (vp[4] * dp[8]) +
  989.                     (vp[3] * dp[9]) +
  990.                     (vp[2] * dp[10]) +
  991.                     (vp[1] * dp[11]) +
  992.                     (vp[0] * dp[12]) +
  993.                     (vp[15] * dp[13]) +
  994.                     (vp[14] * dp[14]) +
  995.                     (vp[13] * dp[15])
  996.                     ) * scalefactor);
  997.  
  998.             buffer->append (channel, clip(pcm_sample));
  999.             } /* for */
  1000.         } break; /* case 12: */
  1001.  
  1002.         case 13: {
  1003.             // fat chance of having this loop unroll
  1004.             for( register const real *dp = d;
  1005.                      dp < d + (32 * 16);
  1006.                      dp += 16, vp += 16 ) {
  1007.                 register int32 pcm_sample;
  1008.  
  1009.                 pcm_sample = (int32)(((vp[13] * dp[0]) +
  1010.                     (vp[12] * dp[1]) +
  1011.                     (vp[11] * dp[2]) +
  1012.                     (vp[10] * dp[3]) +
  1013.                     (vp[9] * dp[4]) +
  1014.                     (vp[8] * dp[5]) +
  1015.                     (vp[7] * dp[6]) +
  1016.                     (vp[6] * dp[7]) +
  1017.                     (vp[5] * dp[8]) +
  1018.                     (vp[4] * dp[9]) +
  1019.                     (vp[3] * dp[10]) +
  1020.                     (vp[2] * dp[11]) +
  1021.                     (vp[1] * dp[12]) +
  1022.                     (vp[0] * dp[13]) +
  1023.                     (vp[15] * dp[14]) +
  1024.                     (vp[14] * dp[15])
  1025.                     ) * scalefactor);
  1026.  
  1027.             buffer->append (channel, clip(pcm_sample));
  1028.             } /* for */
  1029.         } break; /* case 13: */
  1030.  
  1031.         case 14: {
  1032.             // fat chance of having this loop unroll
  1033.             for( register const real *dp = d;
  1034.                      dp < d + (32 * 16);
  1035.                      dp += 16, vp += 16 ) {
  1036.                 register int32 pcm_sample;
  1037.  
  1038.                 pcm_sample = (int32)(((vp[14] * dp[0]) +
  1039.                     (vp[13] * dp[1]) +
  1040.                     (vp[12] * dp[2]) +
  1041.                     (vp[11] * dp[3]) +
  1042.                     (vp[10] * dp[4]) +
  1043.                     (vp[9] * dp[5]) +
  1044.                     (vp[8] * dp[6]) +
  1045.                     (vp[7] * dp[7]) +
  1046.                     (vp[6] * dp[8]) +
  1047.                     (vp[5] * dp[9]) +
  1048.                     (vp[4] * dp[10]) +
  1049.                     (vp[3] * dp[11]) +
  1050.                     (vp[2] * dp[12]) +
  1051.                     (vp[1] * dp[13]) +
  1052.                     (vp[0] * dp[14]) +
  1053.                     (vp[15] * dp[15])
  1054.                     ) * scalefactor);
  1055.  
  1056.             buffer->append (channel, clip(pcm_sample));
  1057.             } /* for */
  1058.         } break; /* case 14: */
  1059.  
  1060.         case 15: {
  1061.             // fat chance of having this loop unroll
  1062.             for( register const real *dp = d;
  1063.                      dp < d + (32 * 16);
  1064.                      dp += 16, vp += 16 ) {
  1065.                 register int32 pcm_sample;
  1066.  
  1067.                 pcm_sample = (int32)(((vp[15] * dp[0]) +
  1068.                     (vp[14] * dp[1]) +
  1069.                     (vp[13] * dp[2]) +
  1070.                     (vp[12] * dp[3]) +
  1071.                     (vp[11] * dp[4]) +
  1072.                     (vp[10] * dp[5]) +
  1073.                     (vp[9] * dp[6]) +
  1074.                     (vp[8] * dp[7]) +
  1075.                     (vp[7] * dp[8]) +
  1076.                     (vp[6] * dp[9]) +
  1077.                     (vp[5] * dp[10]) +
  1078.                     (vp[4] * dp[11]) +
  1079.                     (vp[3] * dp[12]) +
  1080.                     (vp[2] * dp[13]) +
  1081.                     (vp[1] * dp[14]) +
  1082.                     (vp[0] * dp[15])
  1083.                     ) * scalefactor);
  1084.  
  1085.             buffer->append (channel, clip(pcm_sample));
  1086.             } /* for */
  1087.         } break; /* case 15: */
  1088.     }; /* switch( actual_write_pos ) */
  1089. }
  1090.  
  1091. void SynthesisFilter::calculate_pcm_samples(Obuffer *buffer)
  1092. {
  1093.     compute_new_v();
  1094.     compute_pcm_samples(buffer);
  1095.  
  1096.     written_samples += 32;
  1097.     if (actual_write_pos < 15)
  1098.      ++actual_write_pos;
  1099.     else
  1100.      actual_write_pos = 0;
  1101.     actual_v = (actual_v == v1 ? v2 : v1);
  1102.  
  1103.     // initialize samples[]:
  1104.   for (register real *floatp = samples + 32; floatp > samples; )
  1105.      *--floatp = 0.0;
  1106. }
  1107.